package com.yiwan.app.preventionsis.net;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import com.android.volley.http.RequestManager;
import com.app.tianwan.tianwanframe.http.HttpCallBack;
import com.app.tianwan.tianwanframe.utils.LogUtil;
import com.yiwan.app.preventionsis.bean.CheckUpdateData;
import com.yiwan.app.preventionsis.util.UpdateManager;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * http客户端
 */
public class HttpClient {

    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String URL_UPDATE_CHECK = "update.dat";
    private RequestManager mRequestManager;
    Context mContext;

    public HttpClient(Context context){
        mRequestManager = RequestManager.getInstance(context);
        mRequestManager.setDateFormat(DATE_FORMAT);
        mContext = context;
    }

    private RequestManager.TimeoutListener timeoutListener(final RequestManager.RequestListener requestListener){
        return new RequestManager.TimeoutListener() {
            @Override
            public boolean handleTimeout() {
                //TODO 处理超时
                requestListener.onTimeout();
                return true;
            }
        };
    }

    public void checkUpdate(RequestManager.RequestListener<CheckUpdateData> requestListener) {
        if(requestListener == null){
            throw new IllegalArgumentException("HttpListener is null");
        }
        String url = UpdateManager.SERVER_URL + URL_UPDATE_CHECK;
        mRequestManager.gsonGet(CheckUpdateData.class, url, new HashMap<String, String>(), requestListener, null, timeoutListener(requestListener));
    }

    private Map<Object, DownloadTask> downloadTaskMap = new HashMap<>();

    public void download(String url, File saveDir, HttpCallBack httpCallBack){
        if(url == null || saveDir == null){
            return;
        }
        LogUtil.d("start download url: " + url + ", file: " + saveDir);
        mHttpCallback = httpCallBack;
        DownloadTask downloadTask = new DownloadTask(url, saveDir);
        downloadTaskMap.put(url, downloadTask);
        Thread thread = new Thread(downloadTask);
        thread.start();
    }

    /**
     * 重新绑定下载回调
     */
    public void rebindDownloadingCallback(HttpCallBack httpCallBack){
        mHttpCallback = httpCallBack;
    }

    public boolean isDownloading(String url){
        return downloadTaskMap.get(url) != null;
    }

    public void stopDownload(String url){
        DownloadTask downloadTask;
        if((downloadTask = downloadTaskMap.get(url)) != null){
            downloadTask.stopDownloading();
            downloadTaskMap.remove(url);
        }
    }

    private static final int MSG_DOWNLOAD_FAIL = 0;
    private static final int MSG_DOWNLOAD_SUCCESS = 1;
    private static final int MSG_DOWNLOAD_PROGRESSING = 2;
    private static final int MSG_DOWNLOAD_START = 3;

    private static final String KEY_FILE = "file";
    private static final String KEY_SIZE = "size";
    private static final String KEY_FILESIZE = "file size";
    private static final String KEY_EXCEPTION = "exception";
    private static final String KEY_URL = "url";

    private HttpCallBack mHttpCallback;
    private Handler downloadHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DOWNLOAD_FAIL: {
                    LogUtil.d("MSG_DOWNLOAD_FAIL");
                    LogUtil.d((Exception) msg.getData().getSerializable(KEY_EXCEPTION));
                    if(mHttpCallback != null){
                        mHttpCallback.onFailure((Exception) msg.getData().getSerializable(KEY_EXCEPTION), 0, null);
                    }
                    String url = msg.getData().getString(KEY_URL);
                    if (downloadTaskMap.get(url) != null) {
                        downloadTaskMap.remove(url);
                    }
                    break;
                }
                case MSG_DOWNLOAD_SUCCESS: {
                    LogUtil.d("MSG_DOWNLOAD_SUCCESS");
                    if(mHttpCallback != null) {
                        mHttpCallback.onSuccess((File) msg.getData().getSerializable(KEY_FILE));
                    }
                    String url = msg.getData().getString(KEY_URL);
                    if (downloadTaskMap.get(url) != null) {
                        downloadTaskMap.remove(url);
                    }
                    break;
                }
                case MSG_DOWNLOAD_PROGRESSING:
                    LogUtil.d("MSG_DOWNLOAD_PROGRESSING: " + msg.getData().getInt(KEY_SIZE) + "%" + msg.getData().getInt(KEY_FILESIZE));
                    if(mHttpCallback != null) {
                        mHttpCallback.onLoading(msg.getData().getInt(KEY_FILESIZE), msg.getData().getInt(KEY_SIZE));
                    }
                    break;
                case MSG_DOWNLOAD_START:
                    LogUtil.d("MSG_DOWNLOAD_START");
                    if(mHttpCallback != null) {
                        mHttpCallback.onPreStart();
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };

    /**
     * DownloadTask  下载任务
     */
    class DownloadTask implements Runnable {

        private String url;
        private File downDir;
        private String fileName;
        private FileDownloader downloader;
        private int fileSize;

        public DownloadTask(String url, File downFile) {
            this.url = url;
            this.downDir = downFile.getParentFile();
            this.fileName = downFile.getName();
        }

        public void stopDownloading() {
            if (downloader != null) {
                downloader.stopDownloading();
            }
        }

        @Override
        public void run() {
            downloader = new FileDownloader(mContext, url, fileName, downDir, 3);
            downloader.download(new DownloadListener() {
                @Override
                public void onDownloading(int size) {
                    Message msg = downloadHandler.obtainMessage(MSG_DOWNLOAD_PROGRESSING);
                    msg.getData().putString(KEY_URL, url);
                    msg.getData().putSerializable(KEY_SIZE, size);
                    msg.getData().putSerializable(KEY_FILESIZE, fileSize);
                    downloadHandler.sendMessage(msg);
                }

                @Override
                public void onDownloadStart(int fileSize) {
                    Message msg = downloadHandler.obtainMessage(MSG_DOWNLOAD_START);
                    msg.getData().putString(KEY_URL, url);
                    msg.getData().putSerializable(KEY_FILESIZE, fileSize);
                    downloadHandler.sendMessage(msg);
                    DownloadTask.this.fileSize = fileSize;
                }

                @Override
                public void onDownloadFail(Exception e) {
                    Message msg = downloadHandler.obtainMessage(MSG_DOWNLOAD_FAIL);
                    msg.getData().putString(KEY_URL, url);
                    msg.getData().putSerializable(KEY_EXCEPTION, e);
                    downloadHandler.sendMessage(msg);
                }

                @Override
                public void onDownloadSuccess(File saveFile) {
                    Message msg = downloadHandler.obtainMessage(MSG_DOWNLOAD_SUCCESS);
                    msg.getData().putString(KEY_URL, url);
                    msg.getData().putSerializable(KEY_FILE, saveFile);
                    downloadHandler.sendMessage(msg);
                }
            });
        }
    }
}
